package cc.chinagps.gateway.unit.eg.upload;

import cc.chinagps.gateway.aplan.pkg.APlanUtil;
import cc.chinagps.gateway.buff.GBossDataBuff;
import cc.chinagps.gateway.common.Config;
import cc.chinagps.gateway.log.LogManager;
import cc.chinagps.gateway.mq.writer.MQWriter;
import cc.chinagps.gateway.unit.UnitServer;
import cc.chinagps.gateway.unit.UnitSocketSession;
import cc.chinagps.gateway.unit.common.UnitCommon;
import cc.chinagps.gateway.unit.eg.pkg.EGPackage;
import cc.chinagps.gateway.unit.eg.upload.cmds.*;
import cc.chinagps.gateway.util.Constants;
import cc.chinagps.gateway.util.HexUtil;
import cc.chinagps.gateway.util.SystemConfig;
import com.google.protobuf.ByteString;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import java.util.HashMap;
import java.util.Map;

public class EGUploadCmdHandlers {
    private Map<Byte, UploadHandler> handlers = new HashMap<Byte, UploadHandler>();
    private Logger logger_unknown = Logger.getLogger(LogManager.LOGGER_NAME_UNKNOWN_CMD);
    private Logger logger_debug = Logger.getLogger(LogManager.LOGGER_NAME_DEBUG);

    public EGUploadCmdHandlers() {
        initHandlers();
    }

    private void initHandlers() {
        handlers.put((byte) 0x01, new Cmd01());
        handlers.put((byte) 0x02, new Cmd02());
        handlers.put((byte) 0x03, new Cmd03());
        handlers.put((byte) 0x04, new Cmd04());
        handlers.put((byte) 0x06, new Cmd06());
        handlers.put((byte) 0x10, new Cmd10());
        handlers.put((byte) 0x81, new Cmd81());
        handlers.put((byte) 0x82, new Cmd82());
        handlers.put((byte) 0x83, new Cmd83());
        handlers.put((byte) 0x84, new Cmd84());
        handlers.put((byte) 0xA0, new CmdA0());
    }

    public void handleUpload(byte[] source, UnitServer server, UnitSocketSession session) throws Exception {
        EGPackage pkg = EGPackage.parse(source);
        byte cmdId = pkg.getHead().getCmdId();
        String callLetter = null;
        if (session.getUnitInfo() != null) {
            callLetter = session.getUnitInfo().getCallLetter();
        }
        logger_debug.debug("[EG]recev cmdId:" + HexUtil.byteToHexStr(new byte[]{cmdId}) + ";callLetter:"
                + callLetter + ";source:" + HexUtil.byteToHexStr(source));

        if (cmdId != 0x01) {
            UnitCommon.sendUploadTrace(source, server, session);
        }

        savePacket(callLetter, pkg);

        UploadHandler handler = handlers.get(cmdId);
        if (handler != null) {
            boolean canHandle = handler.handlerPackage(pkg, server, session);
            if (!canHandle) {
                String call = null;
                if (session.getUnitInfo() != null) {
                    call = session.getUnitInfo().getCallLetter();
                }
                logger_unknown.info("[EG]no sub handle method, callLetter:" + call + ", source:" + HexUtil.byteToHexStr(source));
            }
        } else {
            String call = null;
            if (session.getUnitInfo() != null) {
                call = session.getUnitInfo().getCallLetter();
            }

            logger_unknown.info("[EG]no sub handle method, callLetter:" + call + ", source:" + HexUtil.byteToHexStr(source));

        }

        sendDataToAPlanClients(source, server, session);

        sendDataToAPlanAlarmClients(source, server, session);
    }

    private boolean needToSave(int cmdId) {
        String packetTypeList = Config.SYS.PACKET_TYPE_LIST;
        String types[] = packetTypeList.split(",");
        for (String type : types) {
            if (cmdId == Integer.valueOf(type)) {
                return true;
            }
        }
        return false;
    }

    private void savePacket(String callLetter, EGPackage pkg) {
        byte cmdId = pkg.getHead().getCmdId();
        if (needToSave(cmdId)) {
            GBossDataBuff.EGPacketInfo.Builder builder = GBossDataBuff.EGPacketInfo.newBuilder();
            if (callLetter != null) {
                builder.setDeviceId(callLetter);
            }
            builder.setVin(pkg.getHead().getVin());
            builder.setPacketType(cmdId);
            builder.setReceiveTime(System.currentTimeMillis());
            builder.setContent(ByteString.copyFrom(pkg.getSource()));
            builder.setGatewayId(Constants.SYSTEM_ID_INT);
            MQWriter.getInstance().addEGPacket(builder.build());
        }
    }

    private void sendDataToAPlanClients(byte[] pkg, UnitServer server, UnitSocketSession session) {
        String isFoshanGw = SystemConfig.getSystemProperty("is_foshan_gw");
        if (StringUtils.isNotBlank(isFoshanGw)) {
            boolean flag = Boolean.valueOf(isFoshanGw);
            if (flag) {
                if (pkg.length >= 3 && pkg[1] == HEARBEAT_START) {
                    return;
                }
            }
        }

        byte[] encode = APlanUtil.encodeAPlanDeliverData(pkg, server.getAPlanServer(), session);
        server.getAPlanServer().broadcastData(encode);
    }

    private static final byte _k = 0x28; // (
    private static final byte _I = 0x49; // I
    private static final byte _T = 0x54; // T
    private static final byte _V = 0x56; // V

    private static final byte HEARBEAT_START = (byte) 0xF0;
    private static final byte LOGIN_START = (byte) 0x80;

    private void sendDataToAPlanAlarmClients(byte[] pkg, UnitServer server, UnitSocketSession session) {
        if (pkg.length >= 17 && pkg[13] == _k && pkg[14] == _I && pkg[15] == _T && pkg[16] == _V) {
            return;
        }

        if (pkg.length >= 3 && pkg[1] == HEARBEAT_START) {
            return;
        }

        if (pkg.length >= 3 && pkg[1] == LOGIN_START) {
            return;
        }

        byte[] encode = APlanUtil.encodeAPlanDeliverData(pkg, server.getAPlanAlarmServer(), session);
        server.getAPlanAlarmServer().broadcastData(encode);
    }
}